#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#include <Semaforo.h>
#include <BaseException.h>

using namespace std;

int main (int argc, char* argv[])
{
	try
	{
		string nombreSemaforo = argv[0];
		char projectId = 't';
		
		pid_t pid = fork ();
		
		if ( pid == 0 )
		{
			cout << "HIJO: PID:" << getpid() << endl;
			cout << "HIJO: Voy a crear el semaforo " << nombreSemaforo << endl;
			
			Semaforo sem(nombreSemaforo, 1, projectId);
			cout << "HIJO: Semaforo creado" << endl;
			
			sem.p();
			cout << "HIJO: Semaforo tomado. Duermo 3 segundos" << endl;
			sleep(3);
			
			sem.v();
			cout << "HIJO: Semaforo liberado. Finalizo" << endl;
			
			return 0;
		}
		else 
		{
			cout << "PADRE: PID:" << getpid() << endl;
			cout << "PADRE: Espero 2 segundos para que mi hijo cree el semaforo" << endl;
			sleep(2);
			
			cout << "PADRE: Voy a abrir el semaforo " << nombreSemaforo << endl;
			Semaforo sem;
			sem.abrir(nombreSemaforo, projectId);
			cout << "PADRE: Semaforo abierto" << endl;
			
			cout << "PADRE: Espero por el semaforo tomado por mi hijo" << endl;
			sem.p();
			cout << "PADRE: Semaforo tomado" << endl;
			
			sem.v();
			cout << "PADRE: Semaforo liberado" << endl;
			
			cout << "PADRE: Espero a que mi hijo finalice" << endl;
			int estado;
			wait( (void*) &estado);
			cout << "PADRE: Mi hijo finalizo" << endl;
			
			sem.eliminar();
			cout << "PADRE: Destrui el semaforo creado por el hijo ya finalizado" << endl;
			
		}
		std::cout << "testSemaforo OK" << std::endl;
	}
	catch (const BaseException& e) {
		std::cerr << "testSemaforo: FAIL" << std::endl;
		std::cerr << e.what() << std::endl;
	}
}